const Controller = require('egg').Controller 
const BMP24 = require('gd-bmp').BMP24
const sha1 = require('sha1')
const xss = require('xss')

function rand (min, max) {
    return Math.random() * (max - min + 1) + min | 0 // 特殊的技巧，|0可以强制转换为整数
  }
  
  // 制造验证码图片
function makeCapcha () {
let img = new BMP24(100, 40)
img.drawCircle(rand(0, 100), rand(0, 40), rand(10, 40), rand(0, 0xffffff))
// 边框
img.drawRect(0, 0, img.w - 1, img.h - 1, rand(0, 0xffffff))
img.fillRect(0, 0, 100, 40, 0xffffff)
// img.fillRect(rand(0, 100), rand(0, 40), rand(10, 35), rand(10, 35), rand(0, 0xffffff));
img.drawLine(rand(0, 100), rand(0, 40), rand(0, 100), rand(0, 40), rand(0, 0xffffff))
// return img;

// 画曲线
let w = img.w / 2
let h = img.h
let color = rand(0, 0xffffff)
let y1 = rand(-5, 5) // Y轴位置调整
let w2 = rand(10, 15) // 数值越小频率越高
let h3 = rand(4, 6) // 数值越小幅度越大
let bl = rand(1, 5)
for (let i = -w; i < w; i += 0.1) {
    let y = Math.floor(h / h3 * Math.sin(i / w2) + h / 2 + y1)
    let x = Math.floor(i + w)
    for (let j = 0; j < bl; j++) {
    img.drawPoint(x, y + j, color)
    }
}

let p = 'ABCDEFGHKMNPQRSTUVWXYZ3456789'
let str = ''
for (let i = 0; i < 4; i++) {
    str += p.charAt(Math.random() * p.length | 0)
}

let fonts = [BMP24.font8x16, BMP24.font12x24, BMP24.font16x32]
let x = 15; let y = 8
for (let i = 0; i < str.length; i++) {
    let f = fonts[Math.random() * fonts.length | 0]
    y = 8 + rand(-10, 10)
    img.drawChar(str[i], x, y, f, rand(0, 0xffffff))
    x += f.w + rand(2, 8)
}
return { code: str, img }
}

class Vertify extends Controller {
    async getCode() {
        const { ctx } = this
        let { code, img } = makeCapcha()
        const create_token  = ctx.helper.createToken
        let token = create_token(code)
        try {
            const vertifyCode = new ctx.model.Code({code, token})
            await vertifyCode.save()
            ctx.body = {
                code: 200,
                msg: '获取验证码成功！',
                data: {
                  token,
                  img: 'data:image/bmp;base64,' + img.getFileData().toString('base64')
                }
              }
        } catch(e) {
            ctx.logger.error(e);
            ctx.body = {
                code: 500,
                msg: '注册失败，服务器异常！'
              }
        }
    }
    async checkCode() {
        // checkTokenCode
        const { ctx } = this 
        let { code, token } = ctx.request.body
        if (!code) {
            ctx.body = {
                code: 500,
                msg: '未填写验证码!'
            }
            return 
        }
        if (!token) {
            ctx.body = {
                code: 500,
                msg: '未传验证码TOKEN!'
            }
            return 
        }
        try{
            let mark = ctx.helper.checkTokenCode({code,token})
            if (!mark) {
                ctx.body = {
                code: 402,
                msg: '登录失败，验证码错误!'
                }
                return
            }
            ctx.body = {
                code: 200,
                msg: '验证码正确!'
            }
        }catch(e){
            ctx.logger.error(e);
            ctx.body = {
                code: 500,
                msg: '注册失败，服务器异常！'
              }
        }
    }
    async register () {
        const { ctx } = this
        let { user_name = '', user_id = '', user_pwd = '', re_user_pwd = '', avatar = '', code = '', code_token = '' } = ctx.request.body
        try {
          if (user_pwd.length < 5) {
            ctx.body = {
              code: 402,
              msg: '注册失败，密码最少为5位！'
            }
            return
          }
          if (user_pwd !== re_user_pwd) {
            ctx.body = {
              code: 402,
              msg: '注册失败，2次密码输入不一致!'
            }
            return
          }
          // 验证码判断
          let mark = await ctx.helper.checkTokenCode({ token: code_token, code })
          if (!mark) {
            ctx.body = {
              code: 402,
              msg: '注册失败，验证码错误!'
            }
            return
          }
          // 判断 user_id 是否重复
          let res = await this.ctx.model.User.find({ user_id })
          if (res.length !== 0) {
            ctx.body = {
              code: 409,
              msg: '注册失败，账号重复了，换一个吧！'
            }
            return
          }
          user_pwd = sha1(sha1(user_pwd + ctx.helper.TOKEN_STR.PWD_ENCODE_STR))
          // 防止xss攻击， 转义
          user_name = xss(user_name)
            const create_token  = ctx.helper.createToken
          let token = create_token(user_id)
          let user = new this.ctx.model.User({ user_id, user_name, user_pwd, avatar, token })
          res = await user.save()
          if (res._id != null) {
            ctx.body = {
              code: 200,
              msg: '注册成功!',
              data: {
                _id: res._id,
                user_id,
                user_name,
                avatar,
                token
              }
            }
          } else {
            ctx.body = {
              code: 500,
              msg: '注册失败，服务器异常!'
            }
          }
        } catch (e) {
          ctx.body = {
            code: 500,
            msg: '注册失败，服务器异常！'
          }
        }
      }
    async login () {
        const { ctx } = this
        let { user_id = '', user_pwd = '', code = '', code_token = ''} = this.ctx.request.body
        try {
            let mark = await this.ctx.helper.checkTokenCode({
                code,
                token:code_token,
            })
            if(!mark) {
                ctx.body = {
                    code: 401,
                    msg: '登录失败，验证码错误!'
                }
                return 
            }
            user_pwd = sha1(sha1(user_pwd + this.ctx.helper.TOKEN_STR.PWD_ENCODE_STR))
            let res = await this.ctx.model.User.findOne({ user_id, user_pwd })
            if (res.id){
                let token = this.ctx.helper.createToken(user_id)
                res.token = token 
                res.save()
                ctx.body = {
                    code: 200,
                    msg: '登录成功!',
                    data: {
                      _id: res._id,
                      user_id:res.user_id,
                      user_name: res.user_name,
                      avatar: res.avatar,
                      sign:res.sign,
                      token
                    }
                  }
            }else {
                ctx.body = {
                    code: 401,
                    msg: '登录失败，用户名或者密码错误!'
                  }
            }
        } catch (e) {
            ctx.logger.error(e);
            ctx.body = {
                code: 500,
                msg: '登录失败，服务器异常!'
            }
        }
    }
}

module.exports = Vertify